var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
import SignerBase from './SignerBase';
import { formatUTCDate, getQueryObject, getSortedParams } from '../tools/utils';
var hmacSHA256 = require('crypto-js/hmac-sha256');
var sha256 = require('crypto-js/sha256');
var AuthorizationHeaderSigner = /** @class */ (function (_super) {
    __extends(AuthorizationHeaderSigner, _super);
    function AuthorizationHeaderSigner() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /// <summary>
    /// Computes an AWS4 signature for a request, ready for inclusion as an
    /// 'Authorization' header.
    /// </summary>
    /// <param name="headers">
    /// The request headers; 'Host' and 'X-Amz-Date' will be added to this set.
    /// </param>
    /// <param name="queryParameters">
    /// Any query parameters that will be added to the endpoint. The parameters
    /// should be specified in canonical format.
    /// </param>
    /// <param name="bodyHash">
    /// Precomputed SHA256 hash of the request body content; this value should also
    /// be set as the header 'X-Amz-Content-SHA256' for non-streaming uploads.
    /// </param>
    /// <param name="awsAccessKey">
    /// The user's AWS Access Key.
    /// </param>
    /// <param name="awsSecretKey">
    /// The user's AWS Secret Key.
    /// </param>
    /// <returns>
    /// The computed authorization string for the request. This value needs to be set as the
    /// header 'Authorization' on the subsequent HTTP request.
    /// </returns>
    AuthorizationHeaderSigner.prototype.ComputeSignature = function (headers, queryParameters, bodyHash, awsAccessKey, awsSecretKey) {
        // first get the date and time for the subsequent request, and convert to ISO 8601 format
        // for use in signature generation
        var requestDateTime = new Date(Date.UTC(2013, 4, 24)); // new Date()
        var dateTimeStamp = formatUTCDate(requestDateTime, this.ISO8601BasicFormat);
        headers.set(this.X_Amz_Date, dateTimeStamp);
        // extract the host portion of the endpoint to include in the signature calculation,
        // unless already set
        if (!headers.has('Host')) {
            var hostHeader = this.EndpointUri.host;
            if (this.EndpointUri.port)
                hostHeader += ':' + this.EndpointUri.port;
            headers.set('Host', hostHeader);
        }
        var dateStamp = formatUTCDate(requestDateTime, this.DateStringFormat);
        var scope = dateStamp + "/" + this.Region + "/" + this.Service + "/" + this.TERMINATOR;
        // canonicalized headers need to be expressed in the query
        // parameters processed in the signature
        var canonicalizedHeaderNames = this.CanonicalizeHeaderNames(headers);
        var canonicalizedHeaders = this.CanonicalizeHeaders(headers);
        // reform the query parameters to (a) add the parameters required for
        // Signature V4 and (b) canonicalize the set before they go into the
        // signature calculation. Note that this assumes parameter names and
        // values added outside this routine are already url encoded
        var paramDictionary = new Map();
        if (queryParameters) {
            paramDictionary = getQueryObject(queryParameters);
        }
        // build the expanded canonical query parameter string that will go into the
        // signature computation
        var canonicalizedQueryParameters = getSortedParams(paramDictionary);
        // express all the header and query parameter data as a canonical request string
        var canonicalRequest = this.CanonicalizeRequest(this.EndpointUri, this.HttpMethod, canonicalizedQueryParameters, canonicalizedHeaderNames, canonicalizedHeaders, bodyHash);
        console.log('\nCanonicalRequest:\n', canonicalRequest);
        // construct the string to be signed
        var stringToSign = this.SCHEME + "-" + this.ALGORITHM + "\n" + dateTimeStamp + "\n" + scope + "\n" + sha256(canonicalRequest); // canonicalRequest need encode
        console.log('\nStringToSign:\n', stringToSign);
        // compute the multi-stage signing key
        var key = this.DeriveSigningKey(awsSecretKey, dateStamp);
        // compute the final signature for the request, place into the result and return to the
        // user to be embedded in the request as needed
        var signatureString = hmacSHA256(stringToSign, key).toString();
        console.log('\nSignature:\n', signatureString);
        var authorization = this.SCHEME + "-" + this.ALGORITHM + " Credential=" + awsAccessKey + "/" + scope + ", SignedHeaders=" + canonicalizedHeaderNames + ", Signature=" + signatureString;
        console.log('\nAuthorization:\n{0}', authorization);
        return authorization;
    };
    return AuthorizationHeaderSigner;
}(SignerBase));
export default AuthorizationHeaderSigner;
